<template>
	<div ref="editors" :style="{ width: '100%', height: height }"></div>
</template>
<script lang="ts" setup>
import jsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker';
import cssWorker from 'monaco-editor/esm/vs/language/css/css.worker?worker';
import htmlWorker from 'monaco-editor/esm/vs/language/html/html.worker?worker';
import tsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker';
import EditorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker';
import * as monaco from 'monaco-editor';
import { ref, onBeforeUnmount, onMounted } from 'vue';

const props = defineProps({
	lang: {
		type: String,
		default: 'javascript',
	},
	height: {
		type: String,
		default: '300px',
	},
	modelValue: {
		type: String,
		default: '',
	},
	defaultValue: {
		type: String,
		default: '',
	},
});
const editors = ref(null);
const emit = defineEmits(['update:modelValue']);
// @ts-ignore
self.MonacoEnvironment = {
	getWorker(_: string, label: string) {
		if (label === 'json') {
			return new jsonWorker();
		}
		if (label === 'css' || label === 'scss' || label === 'less') {
			return new cssWorker();
		}
		if (label === 'html' || label === 'handlebars' || label === 'razor') {
			return new htmlWorker();
		}
		if (['typescript', 'javascript'].includes(label)) {
			return new tsWorker();
		}
		return new EditorWorker();
	},
};

let editor: monaco.editor.IStandaloneCodeEditor;
onBeforeUnmount(() => {
	editor.dispose();
});

onMounted(() => {
	monaco.languages.typescript.javascriptDefaults.setDiagnosticsOptions({
		noSemanticValidation: true,
		noSyntaxValidation: false,
	});
	monaco.languages.typescript.javascriptDefaults.setCompilerOptions({
		target: monaco.languages.typescript.ScriptTarget.ES2016,
		allowNonTsExtensions: true,
	});

	!editor
		? (editor = monaco.editor.create(editors.value as HTMLElement, {
				value: props.modelValue, // 编辑器初始显示文字
				language: props.lang, // 语言支持自行查阅demo
				automaticLayout: true, // 自适应布局
				folding: true, // 是否折叠
				foldingHighlight: true, // 折叠等高线
				theme: 'vs', // 官方自带三种主题vs, hc-black, or vs-dark
				foldingStrategy: 'indentation',
				renderLineHighlight: 'all', // 行亮
				selectOnLineNumbers: true, // 显示行号
				minimap: {
					enabled: false,
				},
				lineNumbers: 'on',
				readOnly: false, // 只读
				fontSize: 16, // 字体大小
				scrollBeyondLastLine: false, // 取消代码后面一大段空白
				overviewRulerBorder: false, // 不要滚动条的边框
		  }))
		: editor.setValue(props.modelValue);
	// console.log(editor)
	// 监听值的变化
	editor.onDidChangeModelContent((val: any) => {
		emit('update:modelValue', editor.getValue());
	});
	loadVal();
});

const reloadCode = (value) => {
	editor.setValue(value || props.modelValue);
};

const loadVal = () => {
	if ((props.modelValue || '').trim() === '') {
		emit('update:modelValue', props.defaultValue);
	}
};

const reloadLang = () => {
	monaco.editor.setModelLanguage(editor.getModel(), props.lang);
};

defineExpose({
	reloadCode,
});
</script>
<style scoped lang="less">
#codeEditBox {
	//  width: 100%;
	height: 50%;
}

.select {
	padding: 10px 0;
	box-sizing: unset;
}

.submit {
	text-align: center;
	padding: 10px 0;
	box-sizing: unset;
}

.e-box {
	width: 100%;
	padding: 10px;
	box-sizing: border-box;
	height: 100%;
	display: flex;
	justify-content: space-between;
	box-sizing: border-box;
	flex-direction: column;
}

.sub-box {
	border-radius: 10px;
	background-color: #999;
	padding: 10px;
	box-sizing: border-box;
	flex: 1;
	color: white;
}
</style>
